fix(tour): tour replays after skip due to poisoned history stack#19
fix(tour): tour replays after skip due to poisoned history stack#19maggo83 merged 3 commits intok9ert:mainfrom
Conversation
Review: PR #19 — Tour replay fix + UI overhaulThis PR is titled as a tour bug fix but is actually a massive UI refactor (8,664 additions / 5,007 deletions across 100+ files, 31 commits). The tour fix itself is a one-liner. The rest is a substantial rework of the MockUI architecture. 👍 What works well
|
When the user triggerred "Restart Tour" from Preferences,
show_menu("start_intro_tour") set current_menu_id to "start_intro_tour"
and never reset it after the tour overlay was started. Any subsequent
forward navigation (e.g. into WalletMenu) called push_menu(), which
pushed "start_intro_tour" onto the history stack. On the way back,
pop_menu() restored "start_intro_tour" as the current menu, hitting
the end-of-show_menu check that unconditionally re-launches the tour —
regardless of whether the user had already skipped it.
Fix: immediately before launching the tour overlay, reset
current_menu_id to "main". This prevents the sentinel value from ever
reaching the history stack, so navigating back from any downstream menu
returns to the main menu without re-triggering the tour.
Replace 10 individual test_a..test_j functions with two scenario-based tests that each encode a complete sequential user journey: - test_tour_skip_scenario : initial boot tour (overlay mechanics + skip path) - test_tour_complete_scenario : manual restart + regression check + full completion Key changes: - Module fixture now flashes firmware fresh, giving a truly clean state (no ui_state_config.json) so the tour auto-start is the real first-boot experience rather than a manually injected state - Regression test for 'tour retriggers after skip + navigate-back' moved to scenario 2 where it is meaningful: the bug only manifests when the tour is launched from within an existing navigation context (back-stack present), not on initial boot with an empty history - Extract flash_firmware() helper in conftest so both _require_device and the tour module fixture share the same flash+wait logic - State machine is now explicit and self-documenting via section comments
38f3f27 to
3d11e3c
Compare
|
|
@k9ert : Do you think my last comment addresses the findings sufficiently or do you think 2./3. need to be reworked now prior merge? |
al-munazzim
left a comment
There was a problem hiding this comment.
Review
CI: ✅ Build Firmware passes
The Fix (navigation_controller.py)
Clean and correct. The one-liner self.ui_state.current_menu_id = "main" right before GuidedTour(...).start() is the minimal fix — prevents the sentinel "start_intro_tour" from ever polluting the history stack. The comment block explaining why is excellent.
No concerns on the fix itself. 👍
Test Refactor (test_tour_device.py)
The consolidation from 10 individual test_a..test_j into 2 scenario functions is a good call:
Positives:
- Module fixture now flashes firmware for a truly clean first-boot state — much more realistic than manually writing
tour_completed=False - Regression test correctly placed in scenario 2 where the bug actually manifests (needs an existing back-stack)
- Section comments make the state machine explicit and easy to follow
flash_firmware()extraction in conftest avoids duplication
One nit:
The two tests are explicitly order-dependent (scenario 2 relies on state from scenario 1). The docstring is honest about this, but pytest doesn't guarantee order by default — it only happens to work because of alphabetical sorting. If someone adds pytest-randomly or reorders, things break silently. Consider either combining into a single test function, or adding a precondition guard at the top of scenario 2 (assert _tour_completed()).
conftest.py
flash_firmware() helper extraction is clean. The else branch fix in _require_device is also an improvement — previously it always waited even after flashing (double wait).
Verdict: Approve. Minimal, correct fix with well-improved tests.
Problem
After triggering "Restart Tour" from Preferences and then skipping the tour, the tour would unexpectedly restart when navigating back to the main menu from WalletMenu.
Root Cause
show_menu("start_intro_tour")setscurrent_menu_idto"start_intro_tour"and never resets it after launching the tour overlay. Any subsequent forward navigation (e.g. into WalletMenu) callspush_menu(), which pushes"start_intro_tour"onto the history stack. On the way back,pop_menu()restores"start_intro_tour"as the current menu, hitting the end-of-show_menucheck that unconditionally re-launches the tour — regardless of whether the user had already skipped it.Fix
Reset
current_menu_idto"main"immediately before launching the tour overlay. This prevents the sentinel value from ever reaching the history stack.Repro Steps
Expected: Returns to main menu
Actual (before fix): Tour restarts